Retrofit2 源码详解

Retrofit2 使用

第一步:定义接口服务类,该类只能是接口类型,里面通过 Retrofit 提供的注解类来定义一些请求方法,比如:

public interface BlogService {

    @GET("blog/{id}")
    Call<ResponseBody> getBlog(@Path("id") int id);
}

该接口定义了一个 GET 请求方法,方法名称为 getBlog ,返回的类型为 Call<ResponseBody>

第二步:创建接口实现类。

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://localhost:4567/")
        .build();

BlogService blogService = retrofit.create(BlogService.class);

首先创建 Retrofit 实例,必须要传入 baseUrl ,不然会报错。 该实例是通过 Builder 模式生成的,里面可以配置相当多的参数,然后通过 create 方法来生成实现类,底层通过动态代理的方式来实现。

第三步:调用相应接口方法,拿到 Call 实例,Call 对象是用来发起同步或异步请求的。

Call<ResponseBody> call = blogService.getBlog(2);

第四步:执行请求。

call.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        System.out.println("success: " + Thread.currentThread().getName());
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        System.out.println("fail: " + Thread.currentThread().getName());
    }
});

Retrofit 初始化

Retrofit 的构造函数只是单纯地进行赋值处理,我们看一下它的实例变量:

// 一个线程安全的、支持高效并发的HashMap,Key 是 Method,Value 是 ServiceMethod,主要是用来做缓存的,避免重复解析接口方法。
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();

// Call 的工厂类,如果不自定义赋值,默认会是 OkHttpClient(实现了 Factory 接口)
final okhttp3.Call.Factory callFactory;
// HttpUrl 类型的地址
final HttpUrl baseUrl;
// 数据转换器
final List<Converter.Factory> converterFactories;
// Call 适配器
final List<CallAdapter.Factory> callAdapterFactories;
// 回调执行器,用来做线程切换的
final @Nullable Executor callbackExecutor;
// 是否提前检查接口注解信息
final boolean validateEagerly;

我们接着看 Builder 类:

public static final class Builder {
    // 该类跟平台有关
    private final Platform platform;
    private @Nullable okhttp3.Call.Factory callFactory;
    private @Nullable HttpUrl baseUrl;
    private final List<Converter.Factory> converterFactories = new ArrayList<>();
    private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
    private @Nullable Executor callbackExecutor;
    private boolean validateEagerly;

    Builder(Platform platform) {
      this.platform = platform;
    }

    public Builder() {
      this(Platform.get());
    }
}

总体跟 Retrofit 的变量差不多,只是多了一个 Platform 变量,该类跟运行的平台相关,源码如下:

class Platform {
  private static final Platform PLATFORM = findPlatform();

  static Platform get() {
    return PLATFORM;
  }

  private static Platform findPlatform() {
    try {
      Class.forName("android.os.Build");
      if (Build.VERSION.SDK_INT != 0) {
        return new Android();
      }
    } catch (ClassNotFoundException ignored) {
    }
    try {
      Class.forName("java.util.Optional");
      return new Java8();
    } catch (ClassNotFoundException ignored) {
    }
    return new Platform();
  }

get 方法会去调用 findPlatform 方法,这个里面很明显跟平台相关,Class.forName 要求 JVM 根据 className 查找并加载指定的类,如果未找到则抛出 ClassNotFoundException 。我们分析 Android 平台,所以会返回一个 Android 对象。

static class Android extends Platform {

    // 获取默认的线程执行器
    @Override public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }

    // 获取默认的 Call 适配器工厂类
    @Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
        @Nullable Executor callbackExecutor) {
      if (callbackExecutor == null) throw new AssertionError();
      // 创建 DefaultCallAdapterFactory
      DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
      return Build.VERSION.SDK_INT >= 24
        ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
        : singletonList(executorFactory);
    }

    // 获取默认的数据转换器工厂类
    @Override List<? extends Converter.Factory> defaultConverterFactories() {
      return Build.VERSION.SDK_INT >= 24
          ? singletonList(OptionalConverterFactory.INSTANCE)
          : Collections.<Converter.Factory>emptyList();
    }

    // 主线程执行器
    static class MainThreadExecutor implements Executor {
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override public void execute(Runnable r) {
        handler.post(r);
      }
    }
  }

该类主要是用于提供框架内部用到的 CallAdapter 工厂类、 Converter 工厂类和线程执行类,这几个类都非常重要,后面再分析。最后我们看一下 build 方法。

public Retrofit build() {
// baseUrl 是必不可少的
  if (baseUrl == null) {
    throw new IllegalStateException("Base URL required.");
  }

  okhttp3.Call.Factory callFactory = this.callFactory;
  if (callFactory == null) {
      // 如果没有传入该对象,则默认创建一个 OkHttpClient
    callFactory = new OkHttpClient();
  }

  // 如果没有传入自定义的线程执行器
  Executor callbackExecutor = this.callbackExecutor;
  if (callbackExecutor == null) {
      // 则拿到默认的执行器,Android 平台上为 MainThreadExecutor
    callbackExecutor = platform.defaultCallbackExecutor();
  }

  // 先添加自定义的 CallAdapter ,最后添加框架默认的 CallAdapter,即 DefaultCallAdapterFactory
  List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
  callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

  List<Converter.Factory> converterFactories = new ArrayList<>(
      1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());

   // 先添加框架的 BuiltInConverters ,然后添加自定义的 converter ,最后添加框架默认的 converter
  converterFactories.add(new BuiltInConverters());
  converterFactories.addAll(this.converterFactories);
  converterFactories.addAll(platform.defaultConverterFactories());

  // 返回 Retrofit 对象
  return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
      unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}

到此,Retrofit 初始化就分析完成了 ,Retrofit 之前定义的变量大部分都涉及到了,具体这些变量怎么使用,我们接着分析。

创建接口实例

创建接口实例是通过 Retrofitcreate 方法来实现的,我们看一下这个方法:

public <T> T create(final Class<T> service) {
  // 提前检查接口方法
  validateServiceInterface(service);
  return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
      new InvocationHandler() {
        private final Platform platform = Platform.get();
        private final Object[] emptyArgs = new Object[0];

        @Override public @Nullable Object invoke(Object proxy, Method method,
            @Nullable Object[] args) throws Throwable {
           // 如果这个方法是声明在 Object 类中,那么不拦截,直接执行
          if (method.getDeclaringClass() == Object.class) {
            return method.invoke(this, args);
          }
          if (platform.isDefaultMethod(method)) {
            return platform.invokeDefaultMethod(method, service, proxy, args);
          }
          // 这句代码非常关键
          return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
        }
      });
}

首先调用了 validateServiceInterface(service) 来提前检查接口方法,这个方法是由 validateEagerly 变量来控制的,源码如下:

if (validateEagerly) {
  Platform platform = Platform.get();
  for (Method method : service.getDeclaredMethods()) {
    if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
      loadServiceMethod(method);
    }
  }
}

重点在于 loadServiceMethod 方法:

ServiceMethod<?> loadServiceMethod(Method method) {
  ServiceMethod<?> result = serviceMethodCache.get(method);
  if (result != null) return result;

  synchronized (serviceMethodCache) {
    result = serviceMethodCache.get(method);
    if (result == null) {
      result = ServiceMethod.parseAnnotations(this, method);
      serviceMethodCache.put(method, result);
    }
  }
  return result;
}

loadServiceMethod 里面会根据 Method 生成一个 ServiceMethod,然后存入 serviceMethodCache ,这是属于提前验证,会提前把接口中每个方法进行解析得到一个 ServiceMethod 对象,然后放入缓存中。 在 loadServiceMethod 中会先取缓存中的值,如果存在就直接返回 ServiceMethod

回到 create 方法,接下来会调用 ProxynewProxyInstance 方法来生成代理对象并强转为 T 类型,即对应的接口类型。由于拿到的是代理对象,所以在调用相应方法时,会先走 InvocationHandler 中的 invoke 方法,里面的重点方法就是 loadServiceMethod ,如果启动了提前检查功能,这里可以直接拿到 ServiceMethod 对象,然后接着调用 invoke 方法。不管有没有提前开启提前检查功能,都需要经过这个方法来获取相应的 ServiceMethod 对象,我们详解分析一下这个方法。

ServiceMethod<?> loadServiceMethod(Method method) {
  // 首先从缓存 serviceMethodCache 中取 ServiceMethod ,如果存在就返回,不存在继续往下走。
  ServiceMethod<?> result = serviceMethodCache.get(method);
  if (result != null) return result;

  synchronized (serviceMethodCache) {
    //这里又从缓存取了一遍,看到这里有没有一种熟悉的感觉,是不是跟 DCL 单例模式特别像,双重校验。
    result = serviceMethodCache.get(method);
    if (result == null) {
      // 获取 ServiceMethod 对象
      result = ServiceMethod.parseAnnotations(this, method);
      // 添加到缓存
      serviceMethodCache.put(method, result);
    }
  }
  return result;
}

上述方法返回的 ServiceMethod 对象最终是通过 ServiceMethodparseAnnotations 方法返回的。ServiceMethod 是一个抽象类,它的子类为 HttpServiceMethodHttpServiceMethod 其实也是一个抽象类,我们先看一下 ServiceMethod 的源码:

abstract class ServiceMethod<T> {
  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
      // 获取 RequestFactory 类,该类包含所有的请求的基本参数
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);

    // 获取返回的类型,比如 Call<ResponseBody>
    Type returnType = method.getGenericReturnType();

    // 检查返回类型的有效性
    if (Utils.hasUnresolvableType(returnType)) {
      throw methodError(method,
          "Method return type must not include a type variable or wildcard: %s", returnType);
    }

    if (returnType == void.class) {
      throw methodError(method, "Service methods cannot return void.");
    }

    // 返回一个 HttpServiceMethod 对象
    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

该方法首先解析请求的基本参数,将解析后的所有请求参数封装到了 RequestFactory 对象,然后检查了方法的返回类型的有效性,最后通过 HttpServiceMethodparseAnnotations 方法来获取 HttpServiceMethod 对象,我们首先分析一下 RequestFactory 类 ,该类里面有大量的解析注解的逻辑,最终会将解析的内容赋值到类变量里面,源码如下:

// 对应的接口方法
private final Method method;
// 请求地址
private final HttpUrl baseUrl;
// 请求方法(GET/POST等)
final String httpMethod;
// 请求相对地址,比如 “blog/{id}”
private final @Nullable String relativeUrl;
// 请求头
private final @Nullable Headers headers;
// 请求报文类型
private final @Nullable MediaType contentType;
// 是否有请求体
private final boolean hasBody;
// 是否使用表单提交方式
private final boolean isFormEncoded;
// 是否使用 Multipart 方式,用来文件上传
private final boolean isMultipart;
// 方法参数处理器,用来解析方法参数注解等
private final ParameterHandler<?>[] parameterHandlers;

以上为 RequestFactory 最重要的字段,由这些字段可知,该类主要是保存请求参数的,而这些参数是通过解析各种注解和方法得到的。我们接着看 HttpServiceMethodparseAnnotations 方法:

static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
    boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
    boolean continuationWantsResponse = false;
    boolean continuationBodyNullable = false;

    Annotation[] annotations = method.getAnnotations();
    Type adapterType;

    ...

    //比如 Call<ResponseBody>
    adapterType = method.getGenericReturnType();

    // 第一步,获取 CallAdapter
    CallAdapter<ResponseT, ReturnT> callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);

    // 比如 ResponseBody
    Type responseType = callAdapter.responseType();

    // 第二步,获取 Converter
    Converter<ResponseBody, ResponseT> responseConverter =
        createResponseConverter(retrofit, method, responseType);

    okhttp3.Call.Factory callFactory = retrofit.callFactory;
    if (!isKotlinSuspendFunction) {            
        // 第三步,返回一个 CallAdapted 对象,该对象继承于 HttpServiceMethod
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    } else if (continuationWantsResponse) {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory,
          callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
    } else {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory,
          callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
          continuationBodyNullable);
    }
  }

上述源码省略了一个参数的校验逻辑,主要关注整体流程,首先看第一步,最终会调用 retrofitcallAdapter 方法:

 public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
   // 注意第一个参数传入了 null
   return nextCallAdapter(null, returnType, annotations);
 }

public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
     Annotation[] annotations) {

   ... 省略参数校验

   //这里的 skipPast 是null, 所以 indexOf 肯定返回的 -1, 所以这里 start = 0
   int start = callAdapterFactories.indexOf(skipPast) + 1;
   for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
     CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
     // adapter 不为null则返回,所以如果自定义的 Adapter 处理不了,返回 null 即可,交给下一个Adapter处理
     if (adapter != null) {
       return adapter;
     }
   }
 }

上述代码中,参数 skipPastnull ,则 start0 开始遍历,如果我们没有自定义 CallAdapter,那么此时获取到的应该是框架内的 DefaultCallAdapterFactory 对象,接着会调用 get 方法来获取 CallAdapter 对象。

@Override public @Nullable CallAdapter<?, ?> get(
     Type returnType, Annotation[] annotations, Retrofit retrofit) {
   // 该默认的适配器只处理原始类型为 Call 类型的,刚好我们自定的适配类型为 Call<ResponseBody>,
   // 所以这里拿到的源始类型为 Call 类型
   if (getRawType(returnType) != Call.class) {
     return null;
   }
   if (!(returnType instanceof ParameterizedType)) {
     throw new IllegalArgumentException(
         "Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
   }

   // 获取返回类型,为 ResponseBody
   final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);

   // 赋值回调执行器
   final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
       ? null
       : callbackExecutor;

   // 构建一个 CallAdapter 返回
   return new CallAdapter<Object, Call<?>>() {
     @Override public Type responseType() {
       return responseType;
     }

     @Override public Call<Object> adapt(Call<Object> call) {
       // 如果 executor 为null ,则直接返回 call ,否则返回 ExecutorCallbackCall (该类包装了 call ,里面有线程切换处理)
       return executor == null
           ? call
           : new ExecutorCallbackCall<>(executor, call);
     }
   };
 }

由源码可知,最后构建了一个 CallAdapter 返回,这个 CallAdapter 很重要,后面的请求流程需要用到。至此第一步分析完毕,接下来看第二步,获取 Converter ,流程跟获取 CallAdapter 类似 ,最后会调用 retrofitresponseBodyConverter 方法:

public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
  // 注意第一个参数传入了 null
  return nextResponseBodyConverter(null, type, annotations);
}

public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
    @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {

  ... 省略参数校验

  //这里的 skipPast 是null, 所以 indexOf 肯定返回的 -1, 所以这里 start = 0    
  int start = converterFactories.indexOf(skipPast) + 1;
  for (int i = start, count = converterFactories.size(); i < count; i++) {
    Converter<ResponseBody, ?> converter =
        converterFactories.get(i).responseBodyConverter(type, annotations, this);
      // converter 不为null则返回,所以如果自定义的 converter 处理不了,返回 null 即可,交给下一个converter 处理
    if (converter != null) {
      return (Converter<ResponseBody, T>) converter;
    }
  }
}

retrofit 初始化的时候有讲到,第一个添加的 converter 为框架的 BuiltInConverters,我们看一下它的 responseBodyConverter 方法:

@Override public @Nullable Converter<ResponseBody, ?> responseBodyConverter(
    Type type, Annotation[] annotations, Retrofit retrofit) {
  // 这里的类型为响应类型 
  if (type == ResponseBody.class) {
    return Utils.isAnnotationPresent(annotations, Streaming.class)
        ? StreamingResponseBodyConverter.INSTANCE
        : BufferingResponseBodyConverter.INSTANCE;
  }
  if (type == Void.class) {
    return VoidResponseBodyConverter.INSTANCE;
  }
  if (checkForKotlinUnit) {
    try {
      if (type == Unit.class) {
        return UnitResponseBodyConverter.INSTANCE;
      }
    } catch (NoClassDefFoundError ignored) {
      checkForKotlinUnit = false;
    }
  }
  return null;
}

这里先说明一下 Type 类型的种类,共有 3 种类型,一种是适配类型(比如 Call),一种是源始类型(比如 Call 类型),一种是响应类型(比如 ResponseBody)。所以该方法主要是根据不同的响应类型来返回不同的 Converter 实例。最后我们看看第三步:

// 第三步,返回一个 CallAdapted 对象,该对象继承于 HttpServiceMethod
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);

就是构建一个 CallAdapted 对象,并把所有的参数都传入该对象,我们看一下它的源码:

static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
  private final CallAdapter<ResponseT, ReturnT> callAdapter;

  CallAdapted(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
      Converter<ResponseBody, ResponseT> responseConverter,
      CallAdapter<ResponseT, ReturnT> callAdapter) {
    // 参数赋值
    super(requestFactory, callFactory, responseConverter);
    // 这是我们获取到的 callAdapter
    this.callAdapter = callAdapter;
  }

  // 实现 HttpServiceMethod 的抽象方法
  @Override protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
    // 直接调用 callAdapter 的 adapt 方法,并把 call 传入
    return callAdapter.adapt(call);
  }
}

该类是 HttpServiceMethod 的内部类,HttpServiceMethod 是一个抽象类,有一个 adapt 的抽象方法。到此,我们分析了代理对象里面的 loadServiceMethod(method) 方法的逻辑,我们再看一下该方法:

// 这句代码非常关键
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);

Call 对象获取流程分析

我们先看一下使用方法:

Call<ResponseBody> call = blogService.getBlog(2);

上述分析已经知道,最终会通过 CallAdapted 实例,并调用 invoke 方法来获取 Call 对象,用于接下来的同步或异步请求。那么我们就从 invoke 方法入手,该方法是在抽象类 ServiceMethod 中定义的抽象方法,具体由 HttpServiceMethod 类实现,那么我们直接看 HttpServiceMethodinvoke 方法:

@Override final @Nullable ReturnT invoke(Object[] args) {
  Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
  return adapt(call, args);
}

该方法共有两步,第一步是构建 OkHttpCall 对象,第二步是调用 adapt 方法,并把 OkHttpCall 和请求参数传入。先分析第一步,直接看 OkHttpCall 的构建方法:

OkHttpCall(RequestFactory requestFactory, Object[] args,
    okhttp3.Call.Factory callFactory, Converter<ResponseBody, T> responseConverter) {
  this.requestFactory = requestFactory;
  this.args = args;
  this.callFactory = callFactory;
  this.responseConverter = responseConverter;
}

非常简单,就是赋值操作,所以重点在于第二步的 CallAdaptedadapt 方法 :

// 实现 HttpServiceMethod 的抽象方法
@Override protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
  // 直接调用 callAdapter 的 adapt 方法,并把 call 传入
  return callAdapter.adapt(call);
}

直接调用 callAdapteradapt 方法,并把 call 传入,之前我们分析到,该 callAdapter 就是在 DefaultCallAdapterFactoryget 方法中返回的,源码再看一下:

@Override public @Nullable CallAdapter<?, ?> get(
     Type returnType, Annotation[] annotations, Retrofit retrofit) {
   // 该默认的适配器只处理原始类型为 Call 类型的,刚好我们自定的适配类型为 Call<ResponseBody>,
   // 所以这里拿到的源始类型为 Call 类型
   if (getRawType(returnType) != Call.class) {
     return null;
   }
   if (!(returnType instanceof ParameterizedType)) {
     throw new IllegalArgumentException(
         "Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
   }

   // 获取返回类型,为 ResponseBody
   final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);

   // 赋值回调执行器
   final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
       ? null
       : callbackExecutor;

   // 构建一个 CallAdapter 返回
   return new CallAdapter<Object, Call<?>>() {
     @Override public Type responseType() {
       return responseType;
     }

     @Override public Call<Object> adapt(Call<Object> call) {
       // 如果 executor 为null ,则直接返回 call ,否则返回 ExecutorCallbackCall (该类包装了 call ,里面有线程切换处理)
       return executor == null
           ? call
           : new ExecutorCallbackCall<>(executor, call);
     }
   };
 }

由于我们是在 Android 平台上运行上,所以 executor 不为 null ,为 MainThreadExecutor ,上述分析 Platform 类时在讲到,所以这里返回了 ExecutorCallbackCall 对象,该对象是 DefaultCallAdapterFactory 的内部类。

发起请求和获取响应流程分析

我们接着上面的流程,看一下 ExecutorCallbackCall 的源码:

static final class ExecutorCallbackCall<T> implements Call<T> {
  final Executor callbackExecutor;
  final Call<T> delegate;

  ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
    // 赋值
    this.callbackExecutor = callbackExecutor;
    this.delegate = delegate;
  }

  @Override public void enqueue(final Callback<T> callback) {
    Objects.requireNonNull(callback, "callback == null");
      // 执行异步请求
    delegate.enqueue(new Callback<T>() {
      @Override public void onResponse(Call<T> call, final Response<T> response) {
          // 通过线程执行器执行任务
        callbackExecutor.execute(() -> {
          if (delegate.isCanceled()) {
              // 失败回调
            callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
          } else {
              // 成功回调
            callback.onResponse(ExecutorCallbackCall.this, response);
          }
        });
      }

      @Override public void onFailure(Call<T> call, final Throwable t) {
      // 通过线程执行器执行任务,失败回调
        callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this, t));
      }
    });
  }

  @Override public boolean isExecuted() {
    return delegate.isExecuted();
  }

  @Override public Response<T> execute() throws IOException {
    // 执行同步请求
    return delegate.execute();
  }

  @Override public void cancel() {
    // 取消请求
    delegate.cancel();
  }

  @Override public boolean isCanceled() {
    // 取消是否被取消
    return delegate.isCanceled();
  }

  @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
  @Override public Call<T> clone() {
   // 深度克隆,返回一个 Call 对象
    return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
  }

  @Override public Request request() {
    // 获取 Request
    return delegate.request();
  }
}

该方法会通过 OkHttpCall 方法来执行相应的同步或异步请求,而在 OkHttpCall 里层会生成真正的请求类来执行请求处理在成功或失败之后,通过线程执行器来切换到主线程来进行用户的回调处理,所以我们在使用时的异步回调是在主线程的,可以直接进行 UI 处理,我们先看一下真正的 call 的生成过程 :

private okhttp3.Call createRawCall() throws IOException {
  okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
  if (call == null) {
    throw new NullPointerException("Call.Factory returned null.");
  }
  return call;
}

这段代码非常熟悉,就是通过 OkHttp 的方式,先构建 Request 对象,然后通过 OkHttpClient 对象的 newCall 方法生成真正的请求类来执行请求,我们看看异步请求的代码:

call.enqueue(new okhttp3.Callback() {
    @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
      Response<T> response;
      try {
          // 解析成想要的格式
        response = parseResponse(rawResponse);
      } catch (Throwable e) {
        throwIfFatal(e);
        callFailure(e);
        return;
      }

      try {
          // 回调成功
        callback.onResponse(OkHttpCall.this, response);
      } catch (Throwable t) {
        throwIfFatal(t);
        t.printStackTrace(); // TODO this is not great
      }
    }

    @Override public void onFailure(okhttp3.Call call, IOException e) {
      callFailure(e);
    }

    private void callFailure(Throwable e) {
      try {
          // 回调失败
        callback.onFailure(OkHttpCall.this, e);
      } catch (Throwable t) {
        throwIfFatal(t);
        t.printStackTrace(); // TODO this is not great
      }
    }

OkHttpCall 对象里层真正发起请求的是 okhttp3.Call 对象,拿到响应结果后,先通过 parseResponse 方法进行数据格式转换,这里就需要用到 converter 了:

Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
     // 获取源始的 ResponseBody 对象
   ResponseBody rawBody = rawResponse.body();

   // Remove the body's source (the only stateful object) so we can pass the response along.
   rawResponse = rawResponse.newBuilder()
       .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
       .build();

   // 根据响应码做相应处理
   int code = rawResponse.code();
   if (code < 200 || code >= 300) {
     try {
       // Buffer the entire body to avoid future I/O.
       ResponseBody bufferedBody = Utils.buffer(rawBody);
       return Response.error(bufferedBody, rawResponse);
     } finally {
       rawBody.close();
     }
   }

   if (code == 204 || code == 205) {
     rawBody.close();
     return Response.success(null, rawResponse);
   }

   // 包装一个可以捕捉异常的对象
   ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
   try {
       // 进行数据转换,默认转换的就是 ResponseBody,即不转换
     T body = responseConverter.convert(catchingBody);
     return Response.success(body, rawResponse);
   } catch (RuntimeException e) {
     // If the underlying source threw an exception, propagate that rather than indicating it was
     // a runtime exception.
     catchingBody.throwIfCaught();
     throw e;
   }
 }

该方法如其名,就是解析响应的,根据响应码做了相应的逻辑处理,然后通过转换器来转换成我们想要的数据类型并返回。到此,我们对每一步的流程都分析了。下面是整体流程图: